package com.example.ipcdemo

import java.lang.RuntimeException
import java.lang.StringBuilder
import java.lang.reflect.Method
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.reflect.KClass

/**
 * 注册类
 */
object  Registry {
    //用于储存服务端的service,key是修饰这个类的注解设置的字符串
    val mServiceMap: ConcurrentHashMap<String,Class<*>> = ConcurrentHashMap()
    //用于储存service的方法,key是service,value是方法集合,方法集合的key是方法的唯一标识,value是方法
    val mMethods:ConcurrentHashMap<Class<*>,ConcurrentHashMap<String,Method>> = ConcurrentHashMap()
    fun register(service: Class<*>){
        service.annotations
        val serviceId = service.getAnnotation(Serviceid::class.java)
            ?: throw RuntimeException("必须使用serviceid注解的服务才能注解")
        val value = serviceId.value
        //添加到集合中
        mServiceMap.put(value,service)
        //在方法集合中找到此服务的方法集合
        var methodMap: ConcurrentHashMap<String, Method>? = mMethods.get(service)
        //如果没有说明没有注册过,那么就添加进去
        if (methodMap==null){
            methodMap = ConcurrentHashMap<String,Method>()
            //kt写法,设置key和value
            mMethods[service] = methodMap
            //再把所有的方法放入方法集合
            for (method in service.methods){
                    //因为有重载方法的存在,所以不能以方法名作为key!,需要带上参数作为key
                val methodStringBuilder = StringBuilder(method.name).append("(")
                //println("methodStringBuilder:$methodStringBuilder")
                //获取这个方法上的所有参数类型
                val parameterTypes = method.parameterTypes
                //如果类型不为空的话
                if (parameterTypes.isNotEmpty()){
                    for (parameter in parameterTypes){
                        //将方法类型全部添加到方法集合中
                        methodStringBuilder.append(parameter.name).append(",")
                        //println("parameter.name:${parameter.name}")
                    }
                    val methodKey = methodStringBuilder.append(")").toString()
                    methodMap[methodKey] = method
                }
            }
        }
        for (service in mServiceMap){
            println("service:$service")
        }
        for (method in mMethods){
           method.value.forEach {
               println(it)
           }
        }
    }


}